package com.magupe.push.common.protocol;

import java.util.HashMap;
import java.util.Map;

import com.magupe.push.common.protocol.request.*;
import com.magupe.push.common.protocol.response.*;
import com.magupe.push.common.serializer.Serializer;
import com.magupe.push.common.serializer.impl.FastJsonSerializer;

import io.netty.buffer.ByteBuf;

/**
 * 通讯协议设计
 * 	魔数----版本号-序列化算法-指令-数据长度----数据-------------......
 * 	4位		1位	1位	   1位    4位
 *
 */
public class PacketCodeC {

	/**
	 * 魔数:代表协议类型
	 */
	public static final int MAGIC_NUMBER = 0x12345678;
	
	public static final PacketCodeC INSTANCE = new PacketCodeC();
	
	/**
	 * 序列化对象类型集合
	 */
	private static final Map<Byte, Class<? extends Packet>> packetTypeMap;
	
	/**
	 * 序列化算法集合
	 */
    private static final Map<Byte, Serializer> serializerMap;
    
    static {
        packetTypeMap = new HashMap<>();
        packetTypeMap.put(Command.LOGIN_REQUEST, LoginRequestPacket.class);
        packetTypeMap.put(Command.LOGIN_RESPONSE, LoginResponsePacket.class);
        packetTypeMap.put(Command.AUTHENTICATION_REQUEST, AuthenticationRequestPacket.class);
        packetTypeMap.put(Command.AUTHENTICATION_RESPONSE, AuthenticationResponsePacket.class);
        packetTypeMap.put(Command.GROUP_MESSAGE_REQUEST, GroupMessageRequestPacket.class);
        packetTypeMap.put(Command.GROUP_MESSAGE_RESPONSE, GroupMessageResponsePacket.class);
        packetTypeMap.put(Command.MESSAGE_REQUEST, MessageRequestPacket.class);
        packetTypeMap.put(Command.MESSAGE_RESPONSE, MessageResponsePacket.class);
        packetTypeMap.put(Command.RPC_MESSAGE_REQUEST, RPCMessageRequestPacket.class);
        packetTypeMap.put(Command.RPC_MESSAGE_RESPONSE, RPCMessageResponsePacket.class);
        packetTypeMap.put(Command.FILE_REQUEST, FileRequestPacket.class);
        packetTypeMap.put(Command.FILE_RESPONSE, FileResponsePacket.class);
        
        serializerMap = new HashMap<>();
        Serializer serializer3 = new FastJsonSerializer();
        serializerMap.put(serializer3.getSerializerAlogrithm(), serializer3);
    }
    
	public void encode(ByteBuf byteBuf, Packet packet) {
        byte[] bytes = Serializer.DEFAULT.serialize(packet);
        
        byteBuf.writeInt(MAGIC_NUMBER);
        byteBuf.writeByte(packet.getVersion());
        byteBuf.writeByte(Serializer.DEFAULT.getSerializerAlogrithm());
        byteBuf.writeByte(packet.getCommand());
        byteBuf.writeInt(bytes.length);
        byteBuf.writeBytes(bytes);
    }
	
	public Packet decode(ByteBuf byteBuf) {
	    byteBuf.skipBytes(4);											// 跳过 magic number
	    byteBuf.skipBytes(1);											// 跳过版本号
	    byte serializeAlgorithm = byteBuf.readByte();					// 序列化算法标识
	    byte command = byteBuf.readByte();								// 指令
	    int length = byteBuf.readInt();									// 数据包长度
	    byte[] bytes = new byte[length];								// 定义byte数组接收数据
	    byteBuf.readBytes(bytes);

	    Class<? extends Packet> requestType = getRequestType(command);	// 根据指令获取序列化对象类型
	    Serializer serializer = getSerializer(serializeAlgorithm);		// 根据序列化算法标识获取序列化工具类

	    if (requestType != null && serializer != null) {
	        return serializer.deserialize(requestType, bytes);
	    }

	    return null;
	}

	private Serializer getSerializer(byte serializeAlgorithm) {
		return serializerMap.get(serializeAlgorithm);
	}

	private Class<? extends Packet> getRequestType(byte command) {
		return packetTypeMap.get(command);
	}

}
